package com.orange.base.component.biztool.simulateddata.service.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.orange.base.component.biztool.simulateddata.service.SimulatedDataEnum;
import com.orange.base.component.biztool.simulateddata.service.SimulatedDataParam;

/**
 * 自定义SQL
 *
 * @author biankudingcha
 * @date: 2022-08-24
 * @since 0.5.0
 */
public class CustomSqlStrategy extends AbstractSimulatedData {

    private static final Pattern SQL_PATTERN = Pattern.compile("\\$\\[.*?\\]");

    private static final ThreadLocal<List<Map<String, Object>>> CONTEXT = new ThreadLocal<List<Map<String, Object>>>();

    @Override
    public Object getValue(SimulatedDataParam param) {
        if (param.getValue() == null || "".equals(param.getValue())) {
            return null;
        }
        List<Map<String, Object>> datas = null;
        if (CONTEXT.get() == null) {
            Map<String, Object> var = new HashMap<String, Object>();
            var.putAll(param.getPrimaryTableData());
            var.putAll(param.getRow());
            String sql = parseSql(param.getValue(), var);
            datas = simulatedDataDao.query(sql, 1, 10000, param.getExtParam());
            if (datas == null || datas.isEmpty()) {
                return null;
            }
            CONTEXT.set(datas);
        } else {
            datas = CONTEXT.get();
        }
        int index = getRandomNumber(0, datas.size() - 1);
        Map<String, Object> data = datas.get(index);
        for (Iterator<Entry<String, Object>> iter = data.entrySet().iterator(); iter.hasNext();) {
            Entry<String, Object> entry = iter.next();
            return entry.getValue();
        }
        return null;
    }

    /**
     * 解析SQL
     *
     * @param sql
     * @param var
     * @return
     */
    private String parseSql(String sql, Map<String, Object> var) {
        Matcher matcher = SQL_PATTERN.matcher(sql);
        while (matcher.find()) {
            String group = matcher.group();
            if (group.startsWith("${") && group.endsWith("}")) {
                String key = group.substring(2, group.length() - 1);
                if (var.containsKey(key)) {
                    sql = sql.replaceFirst(SQL_PATTERN.pattern(), "'" + var.get(key) + "'");
                } else {
                    sql = sql.replaceFirst(SQL_PATTERN.pattern(), "''");
                }
            }

        }
        return sql;
    }

    @Override
    public String getType() {
        return SimulatedDataEnum.CUSTOM_SQL.getName();
    }

    @Override
    public String getCaption() {
        return SimulatedDataEnum.CUSTOM_SQL.getCaption();
    }

}
